package com.christina.engine.processing.impl;

import com.christina.engine.service.executor.ServiceExecutor;
import com.christina.engine.execution.model.ExecutionRequest;
import com.christina.engine.execution.model.ExecutionResult;
import com.christina.engine.processing.AbstractRequestProcessor;
import com.christina.engine.processing.model.ProcessingContext;
import com.christina.engine.processing.model.ProcessingResult;
import com.christina.engine.routing.model.RoutingDecision;
import com.christina.engine.service.factory.DefaultServiceExecutorFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 执行处理器
 * 负责使用工厂模式创建和执行服务，调用具体的业务服务
 */
@Component
public class ExecutionProcessor extends AbstractRequestProcessor {
    
    private static final String PROCESSOR_NAME = "ExecutionProcessor";
    private static final int PROCESSOR_ORDER = 600; // 在路由处理器之后执行
    
    private final DefaultServiceExecutorFactory serviceExecutorFactory;
    
    @Autowired
    public ExecutionProcessor(DefaultServiceExecutorFactory serviceExecutorFactory) {
        super(PROCESSOR_NAME, PROCESSOR_ORDER);
        this.serviceExecutorFactory = serviceExecutorFactory;
    }
    
    @Override
    protected ProcessingResult doProcess(ProcessingContext context) {
        logger.debug("Starting service execution for requestId: {}", context.getRequestId());
        
        try {
            // 获取路由决策
            RoutingDecision routingDecision = getRoutingDecision(context);
            
            // 获取服务执行器
            ServiceExecutor serviceExecutor = getServiceExecutor(routingDecision);
            
            // 构建执行请求
            ExecutionRequest executionRequest = buildExecutionRequest(context, routingDecision);
            
            // 执行服务
            ExecutionResult executionResult = executeService(serviceExecutor, executionRequest);
            
            // 验证执行结果
            validateExecutionResult(executionResult);
            
            // 评估执行质量
            double executionQuality = evaluateExecutionQuality(executionResult, executionRequest);
            
            // 将执行结果存储到处理上下文
            context.setProcessingData("executionResult", executionResult);
            context.setProcessingData("executionRequest", executionRequest);
            context.setProcessingData("executionQuality", executionQuality);
            context.setProcessingData("executorName", serviceExecutor.getName());
            
            // 如果执行质量较低，记录警告
            if (executionQuality < 0.6) {
                logger.warn("Low quality execution for requestId: {}, quality: {}, executor: {}", 
                        context.getRequestId(), executionQuality, serviceExecutor.getName());
            }
            
            logger.debug("Service execution completed for requestId: {}, executor: {}, success: {}, duration: {}ms", 
                    context.getRequestId(), serviceExecutor.getName(), 
                    executionResult.isSuccess(), executionResult.getExecutionDurationMs());
            
            return ProcessingResult.builder()
                    .success(executionResult.isSuccess())
                    .shouldContinue(true)
                    .processorName(PROCESSOR_NAME)
                    .resultData("executionResult", executionResult)
                    .resultData("executorName", serviceExecutor.getName())
                    .resultData("executionSuccess", executionResult.isSuccess())
                    .resultData("executionDuration", executionResult.getExecutionDurationMs())
                    .resultData("executionQuality", executionQuality)
                    .errorMessage(executionResult.isSuccess() ? null : executionResult.getErrorMessage())
                    .build();
                    
        } catch (Exception e) {
            logger.error("Error during service execution for requestId: {}", context.getRequestId(), e);
            throw e;
        }
    }
    
    /**
     * 获取路由决策
     */
    private RoutingDecision getRoutingDecision(ProcessingContext context) {
        RoutingDecision routingDecision = (RoutingDecision) context.getProcessingData().get("routingDecision");
        
        if (routingDecision == null) {
            throw new IllegalStateException("No routing decision found in processing context");
        }
        
        return routingDecision;
    }
    
    /**
     * 获取服务执行器
     */
    private ServiceExecutor getServiceExecutor(RoutingDecision routingDecision) {
        String targetService = routingDecision.getTargetService();
        
        // 首先尝试根据路由决策获取执行器
        Optional<ServiceExecutor> executor = serviceExecutorFactory.getExecutorByRoutingDecision(targetService);
        
        if (executor.isPresent()) {
            logger.debug("Found executor for service: {}", targetService);
            return executor.get();
        }
        
        // 如果没有找到专用执行器，尝试获取通用执行器
        Optional<ServiceExecutor> fallbackExecutor = getFallbackExecutor(targetService);
        
        if (fallbackExecutor.isPresent()) {
            logger.debug("Using fallback executor for service: {}", targetService);
            return fallbackExecutor.get();
        }
        
        throw new IllegalStateException("No executor found for service: " + targetService);
    }
    
    /**
     * 获取兜底执行器
     */
    private Optional<ServiceExecutor> getFallbackExecutor(String targetService) {
        // 尝试获取通用执行器
        var allExecutors = serviceExecutorFactory.getAllExecutors();
        
        // 查找支持该服务类型的执行器
        for (ServiceExecutor executor : allExecutors) {
            if (executor.supports(targetService)) {
                return Optional.of(executor);
            }
        }
        
        // 如果没有找到，创建一个临时的兜底执行器
        return Optional.of(createFallbackExecutor(targetService));
    }
    
    /**
     * 创建兜底执行器
     */
    private ServiceExecutor createFallbackExecutor(String targetService) {
        return new ServiceExecutor() {
            @Override
            public ExecutionResult execute(ExecutionRequest request) {
                logger.warn("Using fallback executor for service: {}", targetService);
                
                return ExecutionResult.builder()
                        .success(false)
                        .errorMessage("服务暂时不可用，请稍后重试")
                        .executorName("FallbackExecutor")
                        .executionDurationMs(0L)
                        .build();
            }
            
            @Override
            public boolean supports(String serviceType) {
                return true; // 兜底执行器支持所有服务类型
            }
            
            @Override
            public String getName() {
                return "FallbackExecutor";
            }
            
            @Override
            public String getSupportedServiceType() {
                return targetService;
            }
            
            @Override
            public boolean isAvailable() {
                return true;
            }
        };
    }
    
    /**
     * 构建执行请求
     */
    private ExecutionRequest buildExecutionRequest(ProcessingContext context, RoutingDecision routingDecision) {
        ExecutionRequest.Builder builder = ExecutionRequest.builder()
                .requestId(context.getRequestId())
                .serviceType(routingDecision.getTargetService())
                .context(context)
                .requestTime(LocalDateTime.now());
        
        // 添加路由决策的执行参数
        Map<String, Object> parameters = new HashMap<>();
        if (routingDecision.getExecutionParameters() != null) {
            parameters.putAll(routingDecision.getExecutionParameters());
        }
        
        // 添加意图参数
        if (context.getRecognizedIntent() != null && 
            context.getRecognizedIntent().getParameters() != null) {
            context.getRecognizedIntent().getParameters().forEach((key, value) -> {
                parameters.put(key, value);
            });
        }
        
        // 添加用户输入
        parameters.put("userInput", context.getOriginalRequest().getUserInput());
        
        // 添加上下文信息
        addContextToParameters(parameters, context);
        
        builder.parameters(parameters);
        
        // 添加元数据
        Map<String, Object> metadata = new HashMap<>();
        metadata.put("intentType", context.getRecognizedIntent() != null ? 
                context.getRecognizedIntent().getType().name() : "UNKNOWN");
        metadata.put("intentConfidence", context.getRecognizedIntent() != null ? 
                context.getRecognizedIntent().getConfidence() : 0.0);
        metadata.put("routingConfidence", routingDecision.getConfidence());
        metadata.put("routingReasoning", routingDecision.getReasoning());
        
        builder.metadata(metadata);
        
        return builder.build();
    }
    
    /**
     * 添加上下文信息到参数中
     */
    private void addContextToParameters(Map<String, Object> parameters, ProcessingContext context) {
        // 添加用户上下文信息
        if (context.getUserContext() != null) {
            parameters.put("userLanguage", context.getUserContext().getProfile() != null ? 
                    context.getUserContext().getProfile().getLanguage() : "zh-CN");
            
            if (context.getUserContext().getPreferences() != null) {
                parameters.put("userPreferences", context.getUserContext().getPreferences().getCustomPreferences());
            }
        }
        
        // 添加对话上下文信息
        if (context.getConversationContext() != null) {
            parameters.put("currentTopic", context.getConversationContext().getCurrentTopic());
            parameters.put("conversationState", context.getConversationContext().getState().name());
            
            if (context.getConversationContext().getConversationHistory() != null) {
                parameters.put("conversationHistorySize", 
                        context.getConversationContext().getConversationHistory().size());
            }
        }
        
        // 添加客户端信息
        if (context.getOriginalRequest().getClientInfo() != null) {
            var clientInfo = context.getOriginalRequest().getClientInfo();
            parameters.put("deviceType", clientInfo.getDeviceType());
            parameters.put("platform", clientInfo.getPlatform());
            // 移除对不存在的getLanguage()方法的调用
        }
    }
    
    /**
     * 执行服务
     */
    private ExecutionResult executeService(ServiceExecutor executor, ExecutionRequest request) {
        try {
            logger.debug("Executing service with executor: {}, serviceType: {}", 
                    executor.getName(), request.getServiceType());
            
            ExecutionResult result = executor.execute(request);
            
            // 如果执行失败，尝试重试（简单的重试策略）
            if (!result.isSuccess() && shouldRetry(result)) {
                logger.debug("Execution failed, attempting retry for requestId: {}", request.getRequestId());
                result = executor.execute(request);
            }
            
            return result;
            
        } catch (Exception e) {
            logger.error("Service execution failed for executor: {}, requestId: {}", 
                    executor.getName(), request.getRequestId(), e);
            
            return ExecutionResult.builder()
                    .success(false)
                    .errorMessage("服务执行异常: " + e.getMessage())
                    .exception(e)
                    .executorName(executor.getName())
                    .executionDurationMs(0L)
                    .build();
        }
    }
    
    /**
     * 判断是否应该重试
     */
    private boolean shouldRetry(ExecutionResult result) {
        // 简单的重试策略：只有在特定错误情况下才重试
        if (result.getErrorMessage() != null) {
            String errorMessage = result.getErrorMessage().toLowerCase();
            return errorMessage.contains("timeout") || 
                   errorMessage.contains("connection") ||
                   errorMessage.contains("temporary");
        }
        return false;
    }
    
    /**
     * 验证执行结果
     */
    private void validateExecutionResult(ExecutionResult result) {
        if (result == null) {
            throw new IllegalStateException("Execution result cannot be null");
        }
        
        if (result.getExecutorName() == null || result.getExecutorName().trim().isEmpty()) {
            logger.warn("Execution result missing executor name");
        }
        
        if (result.getExecutionDurationMs() < 0) {
            logger.warn("Invalid execution duration: {}", result.getExecutionDurationMs());
        }
        
        // 如果执行失败但没有错误信息，记录警告
        if (!result.isSuccess() && 
            (result.getErrorMessage() == null || result.getErrorMessage().trim().isEmpty())) {
            logger.warn("Execution failed but no error message provided");
        }
    }
    
    /**
     * 评估执行质量
     */
    private double evaluateExecutionQuality(ExecutionResult result, ExecutionRequest request) {
        double baseScore = result.isSuccess() ? 0.8 : 0.2;
        
        // 根据执行时间调整分数
        double durationScore = calculateDurationScore(result.getExecutionDurationMs());
        
        // 根据错误信息的完整性调整分数
        double errorHandlingScore = calculateErrorHandlingScore(result);
        
        // 根据结果数据的完整性调整分数
        double dataCompletenessScore = calculateDataCompletenessScore(result);
        
        // 综合评分
        return Math.min(1.0, baseScore * 0.5 + durationScore * 0.2 + 
                             errorHandlingScore * 0.15 + dataCompletenessScore * 0.15);
    }
    
    /**
     * 计算执行时间分数
     */
    private double calculateDurationScore(long durationMs) {
        if (durationMs < 0) return 0.0;
        if (durationMs <= 1000) return 1.0;  // 1秒以内满分
        if (durationMs <= 3000) return 0.8;  // 3秒以内良好
        if (durationMs <= 5000) return 0.6;  // 5秒以内一般
        return 0.4; // 超过5秒较差
    }
    
    /**
     * 计算错误处理分数
     */
    private double calculateErrorHandlingScore(ExecutionResult result) {
        if (result.isSuccess()) {
            return 1.0; // 成功执行满分
        }
        
        if (result.getErrorMessage() != null && !result.getErrorMessage().trim().isEmpty()) {
            return 0.7; // 有错误信息
        }
        
        return 0.3; // 失败但没有错误信息
    }
    
    /**
     * 计算数据完整性分数
     */
    private double calculateDataCompletenessScore(ExecutionResult result) {
        double score = 0.5; // 基础分数
        
        if (result.getResultData() != null) {
            score += 0.3; // 有结果数据
        }
        
        if (result.getMetadata() != null && !result.getMetadata().isEmpty()) {
            score += 0.2; // 有元数据
        }
        
        return Math.min(1.0, score);
    }
    
    @Override
    protected void preProcess(ProcessingContext context) {
        super.preProcess(context);
        context.updateState("EXECUTING_SERVICE");
    }
    
    @Override
    protected void postProcess(ProcessingContext context, ProcessingResult result) {
        super.postProcess(context, result);
        if (result.isSuccess()) {
            context.updateState("SERVICE_EXECUTED");
        } else {
            context.updateState("EXECUTION_FAILED");
        }
    }
    
    @Override
    public boolean supports(ProcessingContext context) {
        // 执行处理器需要路由决策
        return context != null && 
               context.getOriginalRequest() != null &&
               context.getUserId() != null &&
               context.getSessionId() != null &&
               context.getRecognizedIntent() != null &&
               context.getProcessingData().containsKey("routingDecision");
    }
    
    @Override
    protected ProcessingResult handleError(ProcessingContext context, Exception exception) {
        logger.warn("Service execution failed, using emergency fallback for requestId: {}", 
                context.getRequestId(), exception);
        
        try {
            // 创建紧急执行结果
            ExecutionResult emergencyResult = ExecutionResult.builder()
                    .success(false)
                    .errorMessage("服务执行异常，请稍后重试")
                    .exception(exception)
                    .executorName("EmergencyFallback")
                    .executionDurationMs(0L)
                    .build();
            
            context.setProcessingData("executionResult", emergencyResult);
            context.setProcessingData("executionError", exception.getMessage());
            
            return ProcessingResult.builder()
                    .success(false) // 执行失败
                    .shouldContinue(true) // 但继续处理以生成错误响应
                    .processorName(PROCESSOR_NAME)
                    .resultData("executionResult", emergencyResult)
                    .resultData("executorName", "EmergencyFallback")
                    .resultData("executionSuccess", false)
                    .resultData("emergencyFallbackUsed", true)
                    .errorMessage(exception.getMessage())
                    .build();
                    
        } catch (Exception e) {
            logger.error("Failed to create emergency execution result for requestId: {}", 
                    context.getRequestId(), e);
            return super.handleError(context, e);
        }
    }
}